package cn.com.spic.demo.controller;

import cn.com.spic.demo.api.*;
import cn.com.spic.demo.dto.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cpipec.demo.spi.EOSServerRestClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 计划填报相关controller
 */
@RestController
@RequestMapping("/report")
public class ProgressReportController {
    @Autowired
    private ActionProjectService actionProjectService;
    @Autowired
    private ProgressReportService progressReportService;
    @Autowired
    private EmployeeService employeeService;
    @Autowired
    private EOSServerRestClient eosServerRestClient;
    @Value("${file.address}")
    private String fileAddress;
    @Autowired
    private SpecialProjectService specialProjectService;
    @Autowired
    private ReportService reportService;
    @Autowired
    private OrganizationService organizationService;
    /**
     * 计划填报
     * @param request
     * @param progressReportDTO
     */
    @PostMapping("/progress")
    public void insertProgress(HttpServletRequest request, @RequestParam(required = false)ProgressReportDTO[] progressReportDTO) throws ParseException {
        String actionId = request.getParameter("id");
        ProgressReportDTO[] progressReportDTOss = new ProgressReportDTO[1];
//        progressReportDTOss[0] = getprogressReportDTO(actionId);
        if(progressReportDTO!=null && progressReportDTO.length > 0){
            for(int i=0;i<progressReportDTO.length;i++){
                progressReportDTO[i].setActionId(actionId);
            }
        }
        progressReportService.insertProgress(progressReportDTOss);
    }


    /**
     * 从九大项角度查看明细汇总，获取转换参数(转换行动项时用)
     * @param id
     * @return
     */
    @GetMapping("/getSpecParam")
    public List<String> getExchangeParamToSpecial(String id) throws Exception {
        List<String> results = new ArrayList<>();
        List<ActionProejctDTO> dtos = actionProjectService.getActionProDtosByNineId(id);
        for (ActionProejctDTO dto:dtos){
            Long dayNumAll = getDayNum(dto.getEndTime(),dto.getStartTime());
            Long dayNum = getDayNum(new Date().toString(),dto.getStartTime());
            double number = dayNum.doubleValue()/dayNumAll.doubleValue();
            Long actionNum = actionProjectService.getCountBySpecialId(id);
            DecimalFormat df=new DecimalFormat("0.00");
            Double completeRate = null;
            completeRate = (number / actionNum);
            String st=df.format(completeRate);
            results.add(st);
        }
        return results;
    }

    private ProgressReportDTO getprogressReportDTO(ActionProejctDTO actionProejctDTO){
        ProgressReportDTO progressReportDTO = new ProgressReportDTO();
        progressReportDTO.setId("2");
        progressReportDTO.setActionId(actionProejctDTO.getId());
        progressReportDTO.setSpicFirstDeptId(actionProejctDTO.getSpicFirstDeptId());
        progressReportDTO.setSpicSecDeptId(actionProejctDTO.getSpicSecDeptId());
        return progressReportDTO;
    }

    /**
     * 计算时间差
     */
    private Long getDayNum(String day1,String day2) throws Exception {
        Date    a11 = new SimpleDateFormat("yyyy-MM-dd").parse(day1);
        Date    b11 = new SimpleDateFormat("yyyy-MM-dd").parse(day2);
        long dayNum = (a11.getTime()-b11.getTime())/(24*60*60*1000);
        return dayNum;
    }

    @GetMapping("/getReportsByActionId")
    public List<ProgressReportDTO> getProgressReports(String actionId, String creatorId) throws Exception {
        Map<String,String> map = new HashMap<>();

        map.put("actionId",actionId);
        map.put("spicFirstDeptId",employeeService.getEmployeeById(getUserCode()).getOrgCode());

        List<ProgressReportDTO> dtos = progressReportService.getProgressReportdtosNoLimit(map);
        DecimalFormat df=new DecimalFormat("0.00");
        for(ProgressReportDTO dto:dtos){
            dto.setPlanComRate(String.valueOf(1/((double) dtos.size())));
        }
        return dtos;
    }

    /**
     * 文件上传
     * @return
     */
    @PostMapping("/upload")
    public JSONObject upload(String id,MultipartFile file) throws IOException {
        JSONObject object = new JSONObject();
        try{
            String fileName = file.getOriginalFilename();
            String pathName = fileAddress+"/"+id;
            File folder = null;
            if(fileName!=null){
                 folder = new File(pathName,fileName);
            }else {
                 folder = new File(pathName,UUID.randomUUID().toString());
            }
            if(!new File(pathName).isDirectory()){
                new File(pathName).mkdirs();
            }
            file.transferTo(folder);
            ProgressReportDTO dto = progressReportService.getProgressReportdtosNoByActionId(id);
            if(dto.getDef1() !=null){
                dto.setDef1(dto.getDef1().concat(",").concat(folder.getPath()));
            }if(dto.getDef1() ==null){
                dto.setDef1(folder.getPath());
            }
            object.put("path",folder.getPath());
            object.put("name",fileName);
            progressReportService.saveReportProgress(dto);
        }catch(Exception e){
              e.printStackTrace();
        }
        return object;
    }

    /**
     *    文件下载
     * @param request
     * @param response
     * @throws Exception
     */
    @GetMapping("/download")
    public void downloadLog(HttpServletRequest request, HttpServletResponse response) throws Exception {
        this.downloadLogFile(request, response);
    }

    public void downloadLogFile(HttpServletRequest request, HttpServletResponse response) throws Exception {
        try {
            String id = request.getParameter("id");
            //从网站上下载文件时，需要知道下载的是哪一个文件，因此需要获取文件名称(包括后缀)
            String logNameReq = request.getParameter("name");
            //关键点，需要获取的文件所在文件系统的目录，定位准确才可以顺利下载文件
            String filePath = fileAddress+"/"+id;
            File file = new File(filePath,logNameReq);
            //创建一个输入流，将读取到的文件保存到输入流
            InputStream fis = new BufferedInputStream(new FileInputStream(file));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();
            // 重要，设置response的Header
            response.setHeader("Content-Disposition", "attachment;filename=" + new String(logNameReq.getBytes()));
            response.setHeader("Content-Length", "" + file.length());
            //octet-stream是二进制流传输，当不知文件类型时都可以用此属性
            response.setContentType("application/octet-stream");
            //跨域请求，*代表允许全部类型
            response.setHeader("Access-Control-Allow-Origin", "*");
            //允许请求方式
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
            //用来指定本次预检请求的有效期，单位为秒，在此期间不用发出另一条预检请求
            response.setHeader("Access-Control-Max-Age", "3600");
            //请求包含的字段内容，如有多个可用哪个逗号分隔如下
            response.setHeader("Access-Control-Allow-Headers", "content-type,x-requested-with,Authorization, x-ui-request,lang");
            //访问控制允许凭据，true为允许
            response.setHeader("Access-Control-Allow-Credentials", "true");
            //创建一个输出流，用于输出文件
            OutputStream oStream = new BufferedOutputStream(response.getOutputStream());
            //写入输出文件
            oStream .write(buffer);
            oStream .flush();
            oStream .close();
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }
    @PostMapping("/saveReportProgress")
    public JSONObject saveReportProgress(@RequestBody JSONObject object) {
        JSONObject obj = new JSONObject();
        try{
            int i = 0;
            ProgressReportDTO dto = progressReportService.getProgressReportdtosNoByActionId(object.getString("id"));
//            if(String.valueOf(Double.parseDouble(object.getString("actualComRate").replace("%",""))/100).equals(dto.getActualComRate())){
//                obj.put("success","1");
//                return obj;
//            }

            dto.setActualComRate(String.valueOf(Double.parseDouble(object.getString("actualComRate"))/100));
            dto.setNowMessage(object.getString("nowMessage"));
            dto.setTimeOutMessage(object.getString("timeOutMessage"));
            if(object.getString("telephone")!=null){
                dto.setTelephone(object.getString("telephone"));
            }
            dto.setDef(object.getString("achievementResult"));   //成果形式
            dto.setDef4(object.getString("def4"));
            dto.setSubmitDate(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
            dto.setCreatorId(getUserCode());
            i = progressReportService.saveReportProgress(dto);
            if(i>0){
                obj.put("success","0");   // 填报成功
            }else {
                obj.put("success","2");   // 填报失败
            }
            // 保存行动项的同时 将手机号更新到同一行动项中--待验证
            if(object.getString("telephone") != null){
                progressReportService.updateByExampleSelective(dto);
            }
        }catch(Exception e){
              e.printStackTrace();
        }
        return obj;
    }

    /**
     * 进度填报列表
     * @param
     * @return
     */
    @GetMapping("/getAllReports")
    public List<ProgressReportDTO> getAllReports(HttpServletRequest servletRequest) throws Exception {
        Calendar cal = Calendar.getInstance();
        DecimalFormat df=new DecimalFormat("0.000");
        Map<String,String> map = new HashMap<>();
        Map<String,String> map2 = new HashMap<>();

        String submitMonth = null;
        String submitYear = String.valueOf(cal.get(Calendar.YEAR));
//        EmployeeDTO employee = employeeService.getEmployeeById(getUserCode());
        EmployeeDTO employee = employeeService.getEmployeeById(getUserCode());
        List<ProgressReportDTO> reportDTOS = null;
        if(employee.getProfessional().equals("0")||employee.getProfessional().equals("3")){   //填报人
            int month = cal.get(Calendar.MONTH);
//            String agoMonth = String.valueOf(month-1);
//            String agoYear = submitYear;
            if(month<=9){
                submitMonth = "0"+month;
            }else{
                submitMonth = String.valueOf(month);
            }
            if(month==0){
                submitYear = String.valueOf(Integer.parseInt(submitYear)-1);
                submitMonth="12";
            }
            map.put("spicFirstDeptId",employee.getOrgCode());
            map.put("submitYear",submitYear);
            map.put("submitMonth",submitMonth);
            map.put("page",String.valueOf((Integer.parseInt(servletRequest.getParameter("page"))-1)*20));
            map.put("pageNumber","20");

            reportDTOS = progressReportService.getProgressReportdtosNoLimit(map);

//            for (ProgressReportDTO p : reportDTOS){
//                if(actionProjectService.getActionDetailByParentId(p.getActionId()).size()==0){
//                    trueDtos.add(p);
//                }
//            }
            for (ProgressReportDTO po :reportDTOS){
                map2.put("spicFirstDeptId",po.getSpicFirstDeptId());
                map2.put("actionId",po.getActionId());
                List<ActionProejctDTO> actionDto = actionProjectService.getActionProDtos(po.getActionId());
                String nowActualComRate = progressReportService.getMaxReportdtosLimitOne(map2);
                double a = getMonthBetween(actionDto.get(0).getStartTime(),subMonth(new SimpleDateFormat("yyyy-MM-dd").format(new Date()))).size();
                double b = getMonthBetween(actionDto.get(0).getStartTime(),actionDto.get(0).getEndTime()).size();
                po.setPlanComRate(((a/b)*100)>100?"100%":df.format(((a/b)*100))+"%");
                po.setSubmitYear(po.getSubmitYear()+po.getSubmitMonth());
                if(nowActualComRate!=null){
                    po.setNowActualComRate(df.format(Double.parseDouble(nowActualComRate)*100)+"%");
                }else {
                    po.setNowActualComRate(df.format(0)+"%");
                }
                if(po.getActualComRate()!=null){
                    po.setActualComRate(df.format(Double.parseDouble(po.getActualComRate())*100));
                }else {
                    po.setActualComRate(df.format(0));
                }
                po.setActionName(actionDto.get(0).getActionProName());
            }
        }
        return reportDTOS;
    }
    /**
     * 进度填报和审核情况列表
     * @param
     * @return
     */
    @GetMapping("/getjdAndShqkList")
    public List<ProgressReportDTO> getjdAndShqkList(HttpServletRequest servletRequest) throws Exception {
        Calendar cal = Calendar.getInstance();
        DecimalFormat df=new DecimalFormat("0.000");
        Map<String,String> map = new HashMap<>();
        Map<String,String> map2 = new HashMap<>();

        String submitMonth = null;
        String submitYear = String.valueOf(cal.get(Calendar.YEAR));
        EmployeeDTO employee = employeeService.getEmployeeById(getUserCode());
        List<ProgressReportDTO> trueDtos = new ArrayList<>();
        List<ProgressReportDTO> reportDTOS = null;
            int month = cal.get(Calendar.MONTH);
            String agoMonth = String.valueOf(month-1);
            String agoYear = submitYear;
            if(month<=9){
                submitMonth = "0"+month;
            }else{
                submitMonth = String.valueOf(month);
            }
            if(agoMonth.equals("0")){
                agoYear = String.valueOf(Integer.parseInt(submitYear)-1);
                agoMonth="12";
            }
            if(Integer.parseInt(agoMonth)<=9){
                agoMonth = "0"+agoMonth;
            }
            map.put("spicFirstDeptId",employee.getOrgCode());
            map.put("submitYear",submitYear);
            map.put("submitMonth",submitMonth);
            reportDTOS = progressReportService.getjdAndShqkList(map);

        return reportDTOS;
    }
    /**
     * 获取牵头单位或者二级单位的全部行动项
     * @param httpServletRequest
     * @return
     */
    @GetMapping(value = "/getAllActionsByDept" )
    public List<ProgressReportDTO> getAllActionsByDept(HttpServletRequest httpServletRequest){
        String actionId = httpServletRequest.getParameter("id");
        Calendar cal = Calendar.getInstance();
        String submitMonth = null;
        String submitYear = String.valueOf(cal.get(Calendar.YEAR));
        Map<String,String> map = new HashMap<>();
        int month = cal.get(Calendar.MONTH);
        String agoMonth = String.valueOf(month-1);
        String agoYear = submitYear;
        if(month<=9){
            submitMonth = "0"+month;
        }else{
            submitMonth = String.valueOf(month);
        }
        if(agoMonth.equals("0")){
            agoYear = String.valueOf(Integer.parseInt(submitYear)-1);
            agoMonth="12";
        }
        if(Integer.parseInt(agoMonth)<=9){
            agoMonth = "0"+agoMonth;
        }
        map.put("submitYear",submitYear);
        map.put("submitMonth",submitMonth);
        map.put("spicFirstDeptId",actionId);
        return progressReportService.getActionByDept(map);
    }
    /**
     * 进度审核列表
     * @param
     * @return
     */
    @GetMapping("/getReviewProgressList")
    public List<ProgressReportDTO> getReviewProgressList(HttpServletRequest servletRequest) throws Exception {
        Calendar cal = Calendar.getInstance();
        DecimalFormat df=new DecimalFormat("0.000");
        Map<String,String> map = new HashMap<>();
        Map<String,String> map2 = new HashMap<>();

        String submitMonth = null;
        String submitYear = String.valueOf(cal.get(Calendar.YEAR));
        EmployeeDTO employee = employeeService.getEmployeeById(getUserCode());
        List<ProgressReportDTO> trueDtos = new ArrayList<>();
        List<ProgressReportDTO> reportDTOS = null;
        if(employee.getProfessional().equals("1")||employee.getProfessional().equals("3")){   //复核人
            int month = cal.get(Calendar.MONTH);
            if(month<=9){
                submitMonth = "0"+month;
            }else{
                submitMonth = String.valueOf(month);
            }
            if(month==0){
                submitYear = String.valueOf(Integer.parseInt(submitYear)-1);
                submitMonth="12";
            }
            map.put("spicFirstDeptId",employee.getOrgCode());
            map.put("submitYear",submitYear);
            map.put("submitMonth",submitMonth);
//            map.put("def4","1");
            map.put("page",String.valueOf((Integer.parseInt(servletRequest.getParameter("page"))-1)*20));
            map.put("pageNumber","20");
            reportDTOS = progressReportService.getProgressReportdtosNoLimit(map);

//            for (ProgressReportDTO p : reportDTOS){
//                if(actionProjectService.getActionDetailByParentId(p.getActionId()).size()==0){
//                    trueDtos.add(p);
//                }
//            }
            for (ProgressReportDTO po :reportDTOS){
                map2.put("spicFirstDeptId",po.getSpicFirstDeptId());
                map2.put("actionId",po.getActionId());
                List<ActionProejctDTO> actionDto = actionProjectService.getActionProDtos(po.getActionId());
                String nowActualComRate = progressReportService.getMaxReportdtosLimitOne(map2);
                double a = getMonthBetween(actionDto.get(0).getStartTime(),subMonth(new SimpleDateFormat("yyyy-MM-dd").format(new Date()))).size();
                double b = getMonthBetween(actionDto.get(0).getStartTime(),actionDto.get(0).getEndTime()).size();
                po.setPlanComRate(df.format((a/b)*100));
                if(nowActualComRate!=null){
                    po.setNowActualComRate(df.format(Double.parseDouble(nowActualComRate)*100));
                }else {
                    po.setNowActualComRate(df.format(0));
                }
                if(po.getActualComRate()!=null){
                    po.setActualComRate(df.format(Double.parseDouble(po.getActualComRate())*100));
                }else {
                    po.setActualComRate(df.format(0));
                }
                po.setActionName(actionDto.get(0).getActionProName());
            }
        }
        return reportDTOS;
    }
    //进度复核 进度通过或驳回
    @PostMapping("/progressReview")
    public JSONObject progressReview(@RequestBody JSONObject object) {
        String identity = object.getString("identity");
        String actionRateId = object.getString("id");
        JSONObject rtnJSONObject = new JSONObject();

        ProgressReportDTO dto = null;
        int i = 0;
        if(actionRateId!=null && !("").equals(actionRateId)){
            dto = progressReportService.getProgressReportdtosNoByActionId(actionRateId);
        }
        Map<String,String> map = new HashMap<>();
        if(identity!=null && identity.equals("2")){   //通过
            assert dto != null;
            dto.setDef4("2");
            i = progressReportService.saveReportProgress(dto);
        }else if(identity!=null && identity.equals("3")){
            String message = object.getString("message");
            assert dto != null;
            dto.setDef4("3");
            if(dto.getTenantId()!=null && !("").equals(dto.getTenantId())){
                dto.setTenantId(dto.getTenantId().concat(",").concat(message));
            }else {
                dto.setTenantId(message);
            }
            dto.setActualComRate(null);
            dto.setNowMessage(null);
            dto.setTimeOutMessage(null);
            dto.setDef(null);
            dto.setSubmitDate(null);
            dto.setCreatorId(null);
            i =  progressReportService.saveReportProgressSetNull(dto);
        }
        if(i==0){
            rtnJSONObject.put("success","0");
        }else {
            rtnJSONObject.put("success","1");
        }
        return rtnJSONObject;
    }
    //生成进度填报初始化数据
    @GetMapping("/generateProgress")
    public String generateProgress() throws Exception {

        return progressReportService.generateProgress();
    }

    private String getUserCode(){
        JSON json = eosServerRestClient.getCurrentUser();
        JSONObject object = JSONObject.parseObject(json.toJSONString());
        return object.getString("username");
    }
    private static List<String> getMonthBetween(String minDate, String maxDate) throws Exception {
        ArrayList<String> result = new ArrayList<String>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");//格式化为年月

        Calendar min = Calendar.getInstance();
        Calendar max = Calendar.getInstance();

        min.setTime(sdf.parse(minDate));
        min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);

        max.setTime(sdf.parse(maxDate));
        max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);

        Calendar curr = min;
        while (curr.before(max)) {
            result.add(sdf.format(curr.getTime()));
            curr.add(Calendar.MONTH, 1);
        }

        return result;
    }
    private static String subMonth(String date) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        Date dt = sdf.parse(date);

        Calendar rightNow = Calendar.getInstance();

        rightNow.setTime(dt);

        rightNow.add(Calendar.MONTH, -1);
        Date dt1 = rightNow.getTime();

        String reStr = sdf.format(dt1);

        return reStr;
    }

}

